package xyz.ziduo.lapcounter.utils;

import android.app.AlertDialog;
import android.content.Context;
import android.hardware.usb.UsbDeviceConnection;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

import xyz.ziduo.lapcounter.MainActivity;
import xyz.ziduo.lapcounter.R;

public class Utils {

    private static final String TAG = "lap counter: " + Utils.class.getSimpleName();


    // pace to string
    public static String paceToString(double pace) {
        int min = (int)pace / 60;
        int sec = (int)pace % 60;
        if(sec < 10) {
            return min + ":0" + sec;
        } else {
            return min + ":" + sec;
        }
    }


    // 根据里程和时间计算配速，配速即每公里所用时间
    // mileage单位米，time单位毫秒
    // 返回单位秒
    public static double countPace(long time, int mileage) {
        return (double) time / mileage;
    }

    // 根据体重和里程估算消耗热量
    // 简单公式（适用于慢跑或中等强度跑步）
    // 公式：热量消耗（kcal）= 体重（kg）× 距离（km）×0.8
    // weight单位kg，mileage单位米
    public static double countCalorie(int weight, int mileage) {
        return weight * mileage * 0.8 / 1000;
    }

    // 写文件
    // outputStream，写入的流
    // parent，写入的父目录
    // name，文件名
    // data，写入的数据
    public static boolean writeFile(Context context, String parent, String name, String data, boolean append) {
        if(append) {
            String fStr = context.getFilesDir().getAbsolutePath() + "/" + parent + "/" + name;
            File tarFile = new File(fStr);
            if(tarFile.exists()) {
                StringBuilder sb = new StringBuilder();
                try(BufferedReader reader = new BufferedReader(new InputStreamReader(
                        new FileInputStream(tarFile), "UTF-8"))) {
                    for (String line = reader.readLine(); line != null; line = reader.readLine()) {
                        sb.append(line).append("\n");
                    }
                } catch (IOException e) {
                    Log.e(TAG, "write file append mode err, can't read target file.", e);
                    Utils.dplAlert(context, "无法追加内容");
                    return false;
                }
                sb.append(data);
                try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(tarFile), "UTF-8")) {
                    writer.write(sb.toString());
                    writer.flush();
                    return true;
                } catch (IOException e) {
                    Log.e(TAG, "err !", e);
                    Utils.dplAlert(context, "无法追加内容");
                    return false;
                }
            }
            // 如果文件不存在，则追加与不追加一样
        }
        Log.i(TAG, "save dats str:" + data);
        String dir = context.getFilesDir().getAbsolutePath() + "/" + parent;
        File file = new File(dir);
        if(!file.exists()) {
            if(!file.mkdirs()) {
                Log.e(TAG, "Utils writeFile err, mkdirs: " + file.getAbsolutePath());
                return false;
            }
        }
        try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(
                dir + "/" + name), "UTF-8")) {
            writer.write(data);
            writer.flush();
            return true;
        } catch (IOException e) {
            Log.e(TAG, "err !", e);
            return false;
        }
    }

    public static ArrayList<String> readFile(Context context, String parent, String name) {
        String dir = context.getFilesDir().getAbsolutePath() + "/" + parent;
        File file = new File(dir);
        if(!file.exists()) {
            if(!file.mkdirs()) {
                Utils.dplAlert(context, "无法创建目录: " + file.getAbsolutePath());
                Log.e(TAG, "无法创建目录: " + file.getAbsolutePath());
                return null;
            }
        }
        File tarFile = new File(dir + "/" + name);
        if(!tarFile.exists()) return null;
        ArrayList<String> lines = new ArrayList<>();
        try(BufferedReader reader = new BufferedReader(new InputStreamReader(
                new FileInputStream(tarFile), "UTF-8"))) {
            for(String line=reader.readLine(); line!=null; line=reader.readLine()) {
                lines.add(line);
                Log.i(TAG, line);
            }
            return lines;
        } catch (IOException e) {
            Log.e(TAG, "ioexception !", e);
            return null;
        }
    }

    public static void dplAlert(Context context, String alertTxt) {
        View alertView = LayoutInflater.from(context).inflate(R.layout.alert_dialog, null);
        TextView alertTextView = alertView.findViewById(R.id.alert_text);
        alertTextView.setText(alertTxt);
        TextView btn = alertView.findViewById(R.id.alert_btn);
        AlertDialog dialog = new AlertDialog.Builder(context)
                .setCancelable(true)
                .setView(alertView)
                .create();
        btn.setOnClickListener(view -> {
            dialog.dismiss();
        });
        dialog.show();
    }

    /**
     * 用户需知：本串口驱动方法参考了 https://github.com/Hny0305Lin/CH34x/blob/master/CH34xUARTDriver.java，中的相关代码
     *      串口驱动相关代码为 浩瀚银河 反编译得来，二次开发请尊重浩瀚银河和上游作者版权，添加"浩瀚银河"署名和添加醒目文字以让用户知请使用反编译源码
     *      代码许可：https://github.com/Hny0305Lin/LICENSE/blob/main/LICENSE
     * 初始化串口，115200 8N1
     * 适用于CH34x芯片
     * @return 若初始化失败，则返回 false，成功返回 true
     */
    public static boolean uartInit(UsbDeviceConnection connection) {
        byte[] var = new byte[8];
        controlTransfer(connection, 161, 0, 0);
        if (controlTransfer(connection, 95, 0, 0, var, 2) < 0) {
            return false;
        } else {
            controlTransfer(connection, 154, 4882, 55682);
            controlTransfer(connection, 154, 3884, 4);
            if (controlTransfer(connection, 149, 9496, 0, var, 2) < 0) {
                return false;
            } else {
                controlTransfer(connection, 154, 10023, 0);
                controlTransfer(connection, 164, 255, 0);
            }
        }
        Log.e(TAG, "set uart parameters");
        // 设置串口参数：115200 8N1
        char c2;
        int i2;
        int i3;
        c2  = 3;
        i2 = 3;
        i3 = 204;
        int i4 = 156 | (((char) (c2 | 192)) << '\b');
        int m2a = controlTransfer(connection, 161, i4, 0 | 136 | i2 | (i3 << 8));
        return m2a >= 0;
    }


    /**
     * 用户需知：本串口驱动方法参考了 https://github.com/Hny0305Lin/CH34x/blob/master/CH34xUARTDriver.java，中的相关代码
     *      串口驱动相关代码为 浩瀚银河 反编译得来，二次开发请尊重浩瀚银河和上游作者版权，添加"浩瀚银河"署名和添加醒目文字以让用户知请使用反编译源码
     *      代码许可：https://github.com/Hny0305Lin/LICENSE/blob/main/LICENSE
     * 控制传输
     * 适用于CH34x芯片
     */
    private static int controlTransfer(UsbDeviceConnection connection, int i, int i2, int i3) {
        int initTimeOut = 1000;
        return connection.controlTransfer(64, i, i2, i3, null, 0, initTimeOut);
    }


    /**
     * 用户需知：本串口驱动方法参考了 https://github.com/Hny0305Lin/CH34x/blob/master/CH34xUARTDriver.java，中的相关代码
     *      串口驱动相关代码为 浩瀚银河 反编译得来，二次开发请尊重浩瀚银河和上游作者版权，添加"浩瀚银河"署名和添加醒目文字以让用户知请使用反编译源码
     *      代码许可：https://github.com/Hny0305Lin/LICENSE/blob/main/LICENSE
     * 控制传输
     * 适用于CH34x芯片
     */
    private static int controlTransfer(UsbDeviceConnection connection, int i, int i2, int i3, byte[] bArr, int i4) {
        int initTimeOut = 1000;
        return connection.controlTransfer(192, i, i2, i3, bArr, 2, initTimeOut);
    }

}
